function skinsGadget(moduleId)
{
    this.prefs = new Object();
    this.miniMsg = new Object();
    this.tabs = null;
    this.skinData = new Object();
    this.criteria = new Array();
    this.origCss = "";
    this.skinCss = "";
    this.skinName = "";
    this.isIE = false;
    this.testSkin = "";
    this.schedule = "";
    this.ruleId = 0;
    this.moduleId = moduleId;

    this.init = function()
    {
        this.GADGET_VERSION = "1.5";

        this.prefs = new _IG_Prefs(this.moduleId);
        this.miniMsg = new _IG_MiniMessage(this.moduleId, _gel("minimsgs" + this.moduleId));
        this.cssUrl = this.prefs.getString("skinCss");
        this.storedCssUrl = this.prefs.getString("skinCss");
        this.origCss = this.prefs.getString("origCss");
        this.skinName = this.prefs.getString("skinName");
        this.testSkin = this.prefs.getString("testSkin");
        this.readUpdate = this.prefs.getString("readUpdate6");
        this.showUpdates = this.prefs.getBool("showUpdates");
        this.schedule = this.prefs.getString("schedule");
        this.adSupported = this.prefs.getBool("adSupported");

        this.showSchedule = this.prefs.getBool("showSchedule");
        this.showCreate = this.prefs.getBool("showCreate");
        this.showSubmit = this.prefs.getBool("showSubmit");
        this.showNews = this.prefs.getBool("showNews");
        this.showAuthorUrls = this.prefs.getBool("showAuthorUrls");

        this.isIE = document.all;
        this.saveId = 0;
        this.useCache = true;
        this.skinChanges = 0;
        this.orderBy = this.prefs.getInt("orderby");
        this.directoryUrl = "http://bonstio.net/igskins/getSkins.php";
        this.baseCssUrl = "http://igskins.googlecode.com/svn/trunk/css/base2.css";
        this.criteria = [["Default", "by default", []],
                ["Time of day", "until", this.getHours()],
                ["Time of day", "after", this.getHours()],
                ["Weather", "if the weather is", ["sunny", "cloudy", "rainy"]]];

        if (this.adSupported == 1)
        {
            var now = new Date().getTime();
            var lastAdShow = this.prefs.getInt("LAST_AD_SHOW");
            if (lastAdShow != "")
            {
                //Every 4 days
                var interval = 1000 * 60 * 60 * 24 * 4;

                if ((lastAdShow + interval) < now)
                {
                    this.showAd();
                    this.prefs.set("LAST_AD_SHOW", now);
                }
            }
            else
            {
                this.prefs.set("LAST_AD_SHOW", now);
            }
        }

        //store old skin
        var styleSheets = document.getElementsByTagName("link");

        for (var i = 0; i < styleSheets.length; i++)
        {
            if ((styleSheets[i].href.indexOf("skins") >= 0) || (styleSheets[i].href.indexOf("ig.css") >= 0))
            {
                this.origCss = styleSheets[i].href;
                this.prefs.set("origCss", styleSheets[i].href);
                break;
            }
        }

        this.addCustomStyle("igBase", this.baseCssUrl, true);

        //Retrieve the skins and set the active one
        this.getSkins();
    };

    this.renderTabs = function(skinGadget)
    {

        //Show updates as required
        if ((this.showUpdates) && (this.readUpdate == ""))
        {
            var miniMsg = this.miniMsg.createDismissibleMessage('__MSG_update__ - <a href="javascript:void(0)" onclick="this.blur(); this.tabs.setSelectedTab(3);">read more on the news tab </a> or <a href="javascript:void(0)" onclick="this.blur(); skinGadget' + this.moduleId + '.optOut();"> never display these updates</a>', function()
            {
                this.prefs.set("readUpdate6", "true");
            });
            miniMsg.style.margin = "1px";
            miniMsg.style.color = "#000000";
        }


        this.tabs = new _IG_Tabs(this.moduleId, "Directory", _gel("tabContainer" + this.moduleId));

        //Sort out tabs
        this.tabs.alignTabs("left", "3");

        this.tabs.addTab(skinGadget.prefs.getMsg("tabDirectory"),
        {
            contentContainer: _gel("select" + this.moduleId),
            tooltip: skinGadget.prefs.getMsg("tabDirectoryHover")
        });

        if (this.showSchedule)
        {
            this.tabs.addTab(skinGadget.prefs.getMsg("tabSchedule"),
            {
                contentContainer: _gel("schedule" + this.moduleId),
                callback: _IG_Callback(this.getSchedule, this),
                tooltip: skinGadget.prefs.getMsg("tabScheduleHover")
            });
        }

        if (this.showCreate)
        {
            this.tabs.addTab(skinGadget.prefs.getMsg("tabCreate"),
            {
                contentContainer: _gel("create" + this.moduleId),
                callback: _IG_Callback(this.getCreateInstructions, this),
                tooltip: skinGadget.prefs.getMsg("tabCreateHover")
            });
        }

        if (this.showSubmit)
        {
            this.tabs.addTab(skinGadget.prefs.getMsg("tabSubmit"),
            {
                contentContainer: _gel("submit" + this.moduleId),
                callback: _IG_Callback(this.getSubmitInstructions, this),
                tooltip: skinGadget.prefs.getMsg("tabSubmitHover")
            });
        }

        if (this.showNews)
        {
            this.tabs.addTab(skinGadget.prefs.getMsg("tabUpdates"),
            {
                contentContainer: _gel("updates" + this.moduleId),
                callback: _IG_Callback(this.getUpdates, this),
                tooltip: skinGadget.prefs.getMsg("tabUpdatesHover")
            });
        }
    };

    this.getSkins = function()
    {
        var orderby = "";
        // = this.orderBy == 0 ? "?popular=1" : "";
        if (this.orderBy == 0)
        {
            orderby = "?popular=1";
        }
        else if (this.orderBy == 2)
        {
            orderby = "?popular=3"
        }
        var rInterval = this.testSkin == "" ? 60 * 60 : 0;
        _IG_FetchContent(this.directoryUrl + orderby, _IG_Callback(this.onGotSkins, this), { refreshInterval: rInterval });
    };

    this.getCreateInstructions = function(tabId, skinGadget)
    {
        _gel("create" + skinGadget.moduleId).innerHTML = skinGadget.prefs.getMsg("createInstructions");
    };

    this.getSubmitInstructions = function(tabId, skinGadget)
    {
        _gel("submitInstructions" + skinGadget.moduleId).innerHTML = skinGadget.prefs.getMsg("submitInstructions");
    };

    this.getUpdates = function(tabId, skinGadget)
    {
        _gel("updates" + skinGadget.moduleId).innerHTML = skinGadget.prefs.getMsg("updates");
    };

    this.getSchedule = function(tabId, skinGadget)
    {
        var tbl = document.createElement("table");
        tbl.setAttribute("id", "cTable" + skinGadget.moduleId);
        tbl.style.textAlign = "left";
        tbl.style.lineHeight = "2";
        tbl.style.width = "99%";

        var cDiv = document.createElement("div");
        cDiv.setAttribute("id", "cDiv" + skinGadget.moduleId);

        var tblBody = document.createElement("tbody");
        var tblHeader = document.createElement("thead");
        tblHeader.style.textAlign = "center";
        tblBody.setAttribute("id", "rules" + skinGadget.moduleId);
        var row = document.createElement("tr");
        var cell1 = document.createElement("td");
        var cell2 = document.createElement("td");
        cell2.vAlign = "middle";
        cell1.colSpan = "2";
        var use = document.createTextNode("Use ");

        var add = document.createElement("img");
        add.setAttribute("src", "http://igskins.googlecode.com/svn/trunk/images/add.png");
        add.style.border = "0px";
        add.title = "__MSG_tabScheduleAddHover__";
        add.style.verticalAlign = "middle";

        var skins = skinGadget.getControl(skinGadget.skinData, ".name", "sourceArray[i].id");
        skins.setAttribute("id", "skinsRule" + skinGadget.moduleId);

        var condition = skinGadget.getControl(skinGadget.criteria, "[1]");
        condition.onchange = function ()
        {
            skinGadget.conditionChanged(condition.selectedIndex);
        };

        var conditionValue = skinGadget.getControl(skinGadget.criteria[0][2], null);
        conditionValue.setAttribute("id", "conditionValue" + skinGadget.moduleId);

        var addLink = document.createElement("a");
        addLink.setAttribute("href", "javascript:void(0)");
        addLink.onclick = function()
        {
            this.blur();
            var cV = _gel("conditionValue" + skinGadget.moduleId).selectedIndex;
            skinGadget.addRule(row.id, skins.selectedIndex, condition.selectedIndex, cV, skinGadget);
        };
        addLink.appendChild(add);
        var addLinkDiv = document.createElement("div");
        addLinkDiv.style.display = "table-cell";
        addLinkDiv.style.verticalAlign = "middle";
        addLinkDiv.appendChild(addLink);
        addLinkDiv.appendChild(addLink);

        cell1.appendChild(use);
        cell1.appendChild(skins);
        cell1.appendChild(document.createTextNode(" "));
        cell1.appendChild(condition);
        cell1.appendChild(document.createTextNode(" "));
        cell1.appendChild(conditionValue);
        cell1.appendChild(document.createTextNode(" "));
        cell2.appendChild(addLinkDiv);

        row.appendChild(cell1);
        row.appendChild(cell2);
        tblHeader.appendChild(row);
        tbl.appendChild(tblHeader);
        tbl.appendChild(tblBody);
        tbl.appendChild(tblBody);

        var container = _gel("schedule" + skinGadget.moduleId);
        var schedInstr = document.createElement("div");
        schedInstr.className = "bottomMargin" + skinGadget.moduleId;
        schedInstr.innerHTML = skinGadget.prefs.getMsg("scheduleInstructions");

        container.innerHTML = "";

        container.appendChild(schedInstr);
        container.appendChild(tbl);


        //Setup the current schedule
        //addRule : function(ruleId, skinIndex, conditionIndex, conditionValueIndex)
        var rows = skinGadget.schedule.split("$$");
        for (var i = 0; i < rows.length; i++)
        {
            row = rows[i].split("|");
            if (row.length > 2)
            {
                skinGadget.addRule("ruleId" + skinGadget.moduleId + skinGadget.ruleId++, row[0], row[1], row[2], skinGadget)
            }
        }
    };

    this.conditionChanged = function(selectedIndex)
    {
        var select = _gel("conditionValue" + this.moduleId);
        var parent = select.parentNode;
        select.style.display = "none";
        var dropDown = this.getControl(this.criteria[selectedIndex][2]);
        dropDown.setAttribute("id", "conditionValue" + this.moduleId);
        parent.insertBefore(dropDown, select);
        parent.removeChild(select);
    };

    this.saveRules = function()
    {
        //save the current schedule rules
        var rulesString = "";
        var rulesStringArr;
        var rules = _gel("rules" + this.moduleId);
        var limit = rules.childNodes.length;

        for (var i = 0; i < limit; i++)
        {
            var row = rules.childNodes[i];
            if (row.style.display != "none")
            {
                rulesStringArr = row.firstChild.id.split("|");
                rulesStringArr[rulesStringArr.length - 1] = null;
                rulesString += rulesStringArr.join("|") + "$$";
            }
        }

        this.schedule = rulesString;
        this.save();

    };

    this.getSkinFromRules = function()
    {
        //save the current schedule rules
        var skin = "";
        var rules = _gel("rules" + this.moduleId);
        var limit = rules.childNodes.length;
        var rulesStringArr, rulesString;

        for (var i = 0; i < limit; i++)
        {
            var row = rules.childNodes[i];
            if (row.style.display != "none")
            {
                rulesStringArr = row.firstChild.id.split("|");
                rulesStringArr[rulesStringArr.length - 1] = null;
                rulesString += rulesStringArr.join("|") + "$$";
            }
        }

        this.schedule = rulesString;
        this.save();

    };

    this.addRule = function(ruleId, skinIndex, conditionIndex, conditionValueIndex, skinGadget)
    {

        var rules = _gel("rules" + skinGadget.moduleId);
        var row = document.createElement("tr");
        row.setAttribute("id", "ruleId" + skinGadget.moduleId + skinGadget.ruleId++);
        var cell1 = document.createElement("td");
        cell1.setAttribute("id", skinIndex + "|" + conditionIndex + "|" + conditionValueIndex + "|" + skinGadget.moduleId);
        cell1.style.padding = "4px";
        cell1.vAlign = "middle";
        var cell2 = document.createElement("td");
        var cell3 = document.createElement("td");

        var remove = document.createElement("img");
        remove.setAttribute("src", "http://igskins.googlecode.com/svn/trunk/images/cross.png");
        remove.style.border = "0px";
        remove.title = "__MSG_tabScheduleRemoveHover__";

        var removeLink = document.createElement("a");
        removeLink.setAttribute("href", "javascript:void(0)");
        removeLink.onclick = function ()
        {
            this.blur();
            skinGadget.deleteRule(row.id);
        };
        removeLink.appendChild(remove);

        var cvIndex = skinGadget.criteria[conditionIndex][2][conditionValueIndex];

        //might be undefined for the catchall
        cvIndex = cvIndex ? " " + cvIndex : "";

        var item = skinGadget.skinData[skinIndex];
        var thumbUrl = skinGadget.getImageUrl(item.thumbnail);
        var title = item.name + ' by ' + item.author;
        cell1.innerHTML = '<img title = "' + title + '" width="80" height="25" src="' + thumbUrl + '"/>';
        cell2.innerHTML = 'Use the <b>' + item.name + '</b> skin ' + skinGadget.criteria[conditionIndex][1] + cvIndex;
        cell3.appendChild(removeLink);

        row.appendChild(cell1);
        row.appendChild(cell2);
        row.appendChild(cell3);
        rules.appendChild(row);

        skinGadget.saveRules();
    };

    this.deleteRule = function(ruleId)
    {
        _gel(ruleId).style.display = "none";
        this.saveRules();
    };

    this.getControl = function(sourceArray, selector, valueSelector)
    {
        selector = selector ? selector : "";
        valueSelector = valueSelector ? valueSelector : "i";

        var dropDown = document.createElement("select");
        dropDown.style.fontSize = "90%";


        for (var i = 0; i < sourceArray.length; i++)
        {
            var expr = "dropDown.options[dropDown.options.length] = new Option(sourceArray[i]" + selector + ", " + valueSelector + ");";
            eval(expr);
        }

        dropDown.style.display = dropDown.options.length == 0 ? "none" : "";

        return dropDown;
    };

    this.onGotSkins = function(response, skinGadget)
    {
        if ((response == null) || (response == "") || (response.indexOf("ERROR") >= 0))
        {
            _gel("loading" + this.moduleId).innerHTML =
            '<a href="javascript:void(0)" onclick="skinGadget' + skinGadget.moduleId + '.getSkins();"><img style="position:relative; top:5px;" src="http://igskins.googlecode.com/svn/trunk/images/arrow_refresh_small.png" alt="Refresh" title="__MSG_tabDirectoryReload__"/></a>__MSG_tabDirectoryLoadingFailed__ <a href="' + skinGadget.directoryUrl + '">__MSG_tabDirectoryDirectory__</a>.';
        }
        else
        {

            eval("skinGadget" + skinGadget.moduleId + ".skinData = " + response + ";");
            var directory = "";
            var skinClass = "";
            for (var i = 0; i < skinGadget.skinData.length; i++)
            {
                var item = skinGadget.skinData[i];
                //var date = new Date();
                //date.setTime(item.submitted * 1000);
                //var dateString = date.getDate() + "/" + date.getMonth() + "/" + date.getFullYear();
                var thumbUrl = skinGadget.getImageUrl(item.thumbnail);

                skinClass = (item.name == skinGadget.skinName) ? "skinthsel" : "skinth";
                directory += '<div title="' + item.name + ' by ' + item.author + '" style="overflow:hidden;" class="' + skinClass + '" id="' + item.name + skinGadget.moduleId + '" onclick="skinGadget' + skinGadget.moduleId + '.fetchSkin(\'' + item.url + '\', \'' + item.name + '\');	">';
                directory += '<img width="80" height="25" src="' + thumbUrl + '"/>';
                directory += '<b>' + item.name + '</b>';

                if ((skinGadget.showAuthorUrls) && (item.authorUrl != ""))
                {
                    directory += '<a style="text-decoration:none;" onclick="event.cancelBubble=true; this.blur();" title="Visit author&#39;s website" href="' + item.authorUrl + '">&nbsp;&raquo;</a>';
                }
                directory += '</div>';
            }

            skinClass = (skinGadget.skinName == "") ? "skinthsel" : "skinth";
            var offMsg = (skinGadget.testSkin == "") ? skinGadget.prefs.getMsg("modeOff2") : skinGadget.prefs.getMsg("modeTesting");
            var off = '<div class="' + skinClass + '" id="Testing' + skinGadget.moduleId + '" onclick="this.blur(); skinGadget' + skinGadget.moduleId + '.fetchSkin(\'' + skinGadget.testSkin + '\');" class="skinth"><img width="80" height="25" alt="' + offMsg + '" src="/ig/images/skins/classic.png"/><b>' + offMsg + '</b></div>';
            _gel("directory" + skinGadget.moduleId).innerHTML = off + directory;
        }

        //Finish init
        //Render required tabs here so we have the skin data ready for the schedule tab
        if (skinGadget.tabs == null)
        {
            skinGadget.renderTabs(skinGadget);
            //Load a skin if we have one
            var skin = skinGadget.testSkin != "" ? skinGadget.testSkin : skinGadget.cssUrl;
     
            //if we have a skin then set it
            if (skin != "")
            {
                skinGadget.fetchSkin(skin, skinGadget.skinName, true);
            }
            else
            {
                //set off skin
                _gel("Testing" + skinGadget.moduleId).className = "skinthsel";
            }
        }
    };

    this.showAd = function()
    {
        var contentBox = document.createElement("iframe");

        contentBox.frameBorder = 0;
        contentBox.width = '100%';
        contentBox.height = '60px';
        contentBox.scrolling = 'no';
        contentBox.vspace = 0;
        contentBox.hspace = 0;
        contentBox.style.left = 0;
        contentBox.marginWidth = 0;
        contentBox.marginHeight = 0;
        contentBox.style.backgroundColor = "#ffffff";
        contentBox.src = "http://igskins.googlecode.com/svn/trunk/ad.html";

        var ad = this.miniMsg.createStaticMessage(contentBox);
        ad.className = "adClass" + this.moduleId;
    };

    this.submit = function()
    {
        _gel("submitButton" + this.moduleId).disabled = true;

        var skinName = _gel("skinName" + this.moduleId).value;
        var skinAuthor = _gel("skinAuthor" + this.moduleId).value;
        var skinUrl = _gel("skinUrl" + this.moduleId).value;
        var skinAuthorUrl = _gel("skinAuthorUrl" + this.moduleId).value;
        var skinAuthorEmail = _gel("skinAuthorEmail" + this.moduleId).value;

        var url = "http://bonstio.net/igskins/submitSkin.php?" +
                  "skinName=" + skinName + "&" +
                  "skinAuthor=" + skinAuthor + "&" +
                  "skinAuthorUrl=" + skinAuthorUrl + "&" +
                  "skinAuthorEmail=" + skinAuthorEmail + "&" +
                  "skinUrl=" + skinUrl;
        url = encodeURI(url);
        _IG_FetchContent(url, this.onsubmitted, { refreshInterval: 0 });
    };

    this.onsubmitted = function(response)
    {
        _gel("submitButton" + this.moduleId).disabled = false;

        var message = "";
        var miniMsg;
        if (response.indexOf("WARNING") >= 0)
        {
            miniMsg = this.miniMsg.createTimerMessage("__MSG_tabSubmitWarning__ " + response, 10)
            miniMsg.style.backgroundColor = "orange";
            miniMsg.style.color = "black";
            miniMsg.style.margin = "1px";
        }
        else if ((response.indexOf("ERROR") >= 0) || (response.indexOf("HTML") >= 0))
        {
            miniMsg = this.miniMsg.createTimerMessage("__MSG_tabSubmitError__ " + response, 10)
            miniMsg.style.backgroundColor = "red";
            miniMsg.style.color = "white";
            miniMsg.style.margin = "1px";
        }
        else
        {
            miniMsg = this.miniMsg.createTimerMessage("__MSG_tabSubmitOK__", 10);
            miniMsg.style.margin = "1px";
        }
    };

    this.addCustomStyle = function(id, cssUrl, atStart)
    {
        var cssNode = document.createElement('link');
        cssNode.type = 'text/css';
        cssNode.rel = 'stylesheet';
        cssNode.href = cssUrl;
        cssNode.media = 'screen';
        cssNode.setAttribute('id', id);

        if (!atStart)
        {
            _gelstn("head")[0].appendChild(cssNode);
        }
        else
        {
            var insertAt = _gelstn("head")[0];
            insertAt.insertBefore(cssNode, insertAt.firstChild);
        }
    };

    this.getUrl = function(url)
    {
        if (this.useCache)
        {
            //url = _IG_GetCachedUrl(url);
            url = "http://gmodules.com/ig/proxy?url=" + encodeURI(url);
        }

        return url;
    };

    this.getImageUrl = function(url)
    {
        if (this.useCache)
        {
            url = _IG_GetImageUrl(url);
        }

        return url;
    };

    this.setTitle = function(skinName)
    {
        //Get the title
        var title = skinName;
        if ((!title) || (title == ""))
        {
            if (this.testSkin != "")
            {
                title = "Testing";
            }
            else
            {
                title = "Off";
            }
        }

        _IG_SetTitle("Custom iGoogle Skins : " + title, this.moduleId);
    };

    this.fetchSkin = function(cssUrl, skinName, init)
    {
        //unless initializing, check for dirty
        if (!init)
        {
            //has the skin changed?
            if ((cssUrl) && (cssUrl == this.cssUrl))
            {
                //nochange
                return;
            }
        }

        //Check for schedule

        //Figure and set title
        this.setTitle(skinName);

        //Sort the save button
        _gel('save' + this.moduleId).disabled = (cssUrl == this.storedCssUrl);

        //turn off last skin in UI
        var current = _gel(this.skinName + this.moduleId);
        if (current)
        {
            current.className = "skinth";
        }

        //set the new one
        var newSkin = _gel((skinName || "Testing") + this.moduleId);
        if (newSkin)
        {
            newSkin.className = "skinthsel";
        }

        if ((!cssUrl) || (cssUrl == this.testSkin))
        {
            //render a test one using no cache
            if (this.testSkin != "")
            {
                this.useCache = false;
                _IG_FetchContent(this.testSkin, _IG_Callback(this.setSkin, this), { refreshInterval: 0 });
            }
            else
            //find ext style sheet and revert to orig theme - replace or delete
            {
                var extCss = _gel("ext_css");
                if (extCss)
                {

                    //delete or replace style custom sheet
                    if (this.origCss != "")
                    {
                        extCss.setAttribute("href", this.origCss);
                    }
                }
            }
        }
        else
        {
            //fetch and inspect a remote skin
            this.useCache = true;
            _IG_FetchContent(cssUrl, _IG_Callback(this.setSkin, this), { refreshInterval: 60 });
        }

        //Store the cssUrl - the non-cached version
        this.cssUrl = cssUrl ? cssUrl : "";
        this.skinName = skinName ? skinName : "Testing";
    };

    this.isSafeBeta = function(response, skinName)
    {
        //todo fixup
        response = response.toLowerCase();
        return !((response.indexOf("@import") >= 0) || (response.indexOf(".js") >= 0) || (response.indexOf(".swf") >= 0) || (response.indexOf(".vbs") >= 0) || (response.indexOf("<link") >= 0));
    };

    this.setSkin = function(response, skinGadget)
    //this.setSkin = function(response, cssUrl, skinName)
    {
        if ((response) && (response != ""))
        {
            if (!skinGadget.isSafeBeta(response, skinGadget.skinName))
            {
                //blacklist
                alert(skinGadget.skinName + " skin - critical error: failed to render skin - could not be found or rendered. Please report this to skins@bonstio.net along with the URL " + skinGadget.cssUrl);
                return;
            }
        }

        //Look for external stylesheet
        var extCss = _gel("ext_css");

        //Use the cache unless testing
        var cssUrl = skinGadget.getUrl(skinGadget.cssUrl);

        //simplest case: replace css with external one
        if ((extCss) && (cssUrl))
        {
            extCss.parentNode.removeChild(extCss);
            skinGadget.addCustomStyle("ext_css", cssUrl);

        }
        else if ((!extCss) && (cssUrl))
        {
            skinGadget.addCustomStyle("ext_css", cssUrl);
        }

        if ((skinGadget.adSupported == 1) && (skinGadget.skinChanges++ == 4))
        {
            skinGadget.showAd();
        }
    };


    this.optOut = function()
    {
        this.prefs.set("showUpdates", false);
    };


    this.scoreUsage = function()
    {
        //Log current skin for usage stats. This cannot really be cached otherwise my db won't update
        _IG_FetchContent(encodeURI("http://bonstio.net/igskins/currentSkin.php?name=" + this.skinName), function(response)
        {
        }, { refreshInterval: 0 });
    };

    this.showFilter = function(show)
    {
        if (show)
        {
            _gel("filterBox" + this.moduleId).style.display = "block";
            _gel("filterString" + this.moduleId).focus();
			this.filter();
        }
        else
        {
            _gel("filterString" + this.moduleId).blur();
            _gel("filterBox" + this.moduleId).style.display = "none";
        }
    };

    this.filter = function()
    {
        var saveCommand = "skinGadget" + this.moduleId + ".doFilter(" + ++this.saveId + ");";
        window.setTimeout(saveCommand, 250);
    };

    this.doFilter = function(id)
    {
        if ((id) && (id < this.saveId))
        {
            return;
        }

        var filterString = _gel("filterString" + this.moduleId).value;

        filterString = filterString.toLowerCase();

        var directory = _gel("directory" + this.moduleId);
        for (var i = 0, limit = directory.childNodes.length; i < limit; i++)
        {
            var skinDiv = directory.childNodes[i];
            if (skinDiv.title.toLowerCase().indexOf(filterString) < 0)
            {
                skinDiv.style.display = "none";
            }
            else
            {
                skinDiv.style.display = "";
            }
        }
    };

    this.save = function()
    {
        var saveCommand = "skinGadget" + this.moduleId + ".setPrefs(" + ++this.saveId + ");";
        window.setTimeout(saveCommand, 1);
        //do it now - i.e. 1
        _gel("save" + this.moduleId).disabled = true;
    };

    this.setPrefs = function(save)
    {
        if ((save) && (save < this.saveId))
        {
            return;
        }

        this.prefs.set("skinCss", this.cssUrl, "skinName", this.skinName, "schedule", this.schedule);

        //if dirty
        if (this.cssUrl != this.storedCssUrl)
        {
            this.storedCssUrl = this.cssUrl;
            this.scoreUsage();
        }
    };

    this.getHours = function()
    {
        var hours = new Array();
        var time = "";
        for (var i = 0; i < 24; i++)
        {
            time = i + ":00";
            while (time.length < 5)
            {
                time = "0" + time;
            }
            hours[hours.length] = time;

            time = i + ":30";
            while (time.length < 5)
            {
                time = "0" + time;
            }
            hours[hours.length] = time;
        }

        return hours;
    }

    this.init();
};
